package com.czc.weather.push.weather.service;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.czc.weather.push.weather.entity.PushData;
import com.czc.weather.push.weather.utils.DateUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

@Service
public class WxPushService {

    @Autowired
    private WeathernfoService weathernfoService;
    
    @Autowired
    private PushDataService pushDataService;

    // 通过appToken获取用户uid数组
    public List<String> getWxPushUids(PushData pushData) throws IOException {
        System.out.println("开始获取用户UID，AppToken: " + pushData.getAppToken());
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://wxpusher.zjiecode.com/api/fun/wxuser/v2?appToken=" + pushData.getAppToken()
                        + "&page=1&pageSize=100&type=0")
                .get()
                .build();
        Response response = client.newCall(request).execute();
        String responseBody = response.body().string();
        System.out.println("获取用户UID响应: " + responseBody);

        // 检查响应状态码，判断AppToken是否有效
        if (!response.isSuccessful()) {
            System.err.println("获取用户UID失败，HTTP状态码: " + response.code());
            // 如果是401或403错误，说明AppToken无效
            if (response.code() == 401 || response.code() == 403) {
                System.err.println("AppToken无效，将删除该推送数据: " + pushData.getMobile());
                pushDataService.removePushDataByMobile(pushData.getMobile());
            }
            response.close();
            return new ArrayList<>();
        }

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(responseBody);
        
        // 检查API返回的code字段，判断AppToken是否有效
        JsonNode codeNode = rootNode.path("code");
        // WxPusher API返回1000表示处理成功
        if (codeNode.isMissingNode() || !"1000".equals(codeNode.asText())) {
            System.err.println("获取用户UID失败，API返回错误代码: " + (codeNode.isMissingNode() ? "无code字段" : codeNode.asText()));
            // 如果code不是1000，可能是AppToken无效
            // WxPusher API中，AppToken无效通常返回特定的错误码
            String errorCode = codeNode.asText();
            if (!codeNode.isMissingNode() && ("401".equals(errorCode) || "403".equals(errorCode) || "1001".equals(errorCode) || "1004".equals(errorCode))) {
                System.err.println("AppToken无效，将删除该推送数据: " + pushData.getMobile());
                pushDataService.removePushDataByMobile(pushData.getMobile());
            }
            response.close();
            return new ArrayList<>();
        }
        
        JsonNode recordsNode = rootNode.path("data").path("records");

        List<String> uids = new ArrayList<>();
        for (JsonNode record : recordsNode) {
            String uid = record.path("uid").asText();
            if (!uid.isEmpty()) {
                uids.add(uid);
            }
        }
        System.out.println("成功获取用户UID数量: " + uids.size());
        response.close();
        return uids;
    }

    // 推送消息
    public void pushWeatherInfo(List<String> uids, PushData pushData) throws IOException {
        System.out.println("开始查询未来24小时天气信息，地区编码: " + pushData.getAreaCode());
        JSONObject weatherInfo = weathernfoService.getWeatherInfo(pushData.getAreaCode());
        System.out.println("成功获取天气信息: " + weatherInfo.toJSONString());
        
        JSONObject json = new JSONObject();
        json.put("appToken", pushData.getAppToken());
        json.put("contentType", "2"); // contentType=2意为使用html代码
        json.put("summary", "宝宝请查收，未来二十四小时天气");
        json.put("verifyPayType", "0");
        json.put("uids", uids);
        json.put("content", buildContent(weatherInfo.toString(), pushData));
        
        System.out.println("准备推送消息，用户数量: " + uids.size());
        System.out.println("推送内容预览: " + json.toJSONString().substring(0, Math.min(200, json.toJSONString().length())) + "...");
        
        // 创建 OkHttpClient 实例
        OkHttpClient client = new OkHttpClient().newBuilder()
                .connectTimeout(5, TimeUnit.SECONDS) // 连接超时时间
                .readTimeout(5, TimeUnit.SECONDS) // 读取超时时间
                .writeTimeout(5, TimeUnit.SECONDS) // 写入超时时间
                .build();
        // 创建 RequestBody，指定媒体类型为 JSON
        RequestBody body = RequestBody.create(json.toString(), MediaType.parse("application/json; charset=utf-8"));
        // 构建请求
        Request request = new Request.Builder()
                .url("https://wxpusher.zjiecode.com/api/send/message")
                .post(body)
                .build();
        System.out.println(LocalDateTime.now() + "：开始推送微信消息");
        // 发送请求并处理响应
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String responseBody = response.body().string();
            System.out.println("消息推送成功！响应: " + responseBody);
            
            // 检查响应内容中的code字段，判断AppToken是否有效
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode rootNode = objectMapper.readTree(responseBody);
            JsonNode codeNode = rootNode.path("code");
            
            // 如果code不是1000，说明推送可能失败，需要检查是否是AppToken问题
            if (!codeNode.isMissingNode() && !"1000".equals(codeNode.asText())) {
                System.err.println("消息推送失败，API返回错误代码: " + codeNode.asText());
                // 如果是特定的错误码，说明AppToken无效
                String errorCode = codeNode.asText();
                if ("401".equals(errorCode) || "403".equals(errorCode) || "1001".equals(errorCode) || "1004".equals(errorCode)) {
                    System.err.println("AppToken无效，将删除该推送数据: " + pushData.getMobile());
                    pushDataService.removePushDataByMobile(pushData.getMobile());
                }
            }
        } else {
            System.err.println("消息推送失败，HTTP状态码: " + response.code());
            // 如果是401或403错误，说明AppToken无效
            if (response.code() == 401 || response.code() == 403) {
                System.err.println("AppToken无效，将删除该推送数据: " + pushData.getMobile());
                pushDataService.removePushDataByMobile(pushData.getMobile());
            }
        }
        response.close();
    }

    public static String getEveryJoker() throws IOException {
        System.out.println("开始获取每天一笑");
        OkHttpClient client = new OkHttpClient();
        Request request = null;
        Response response = null;
        request = new Request.Builder()
                .url("https://tools.mgtv100.com/external/v1/pear/duanZi")
                .get()
                .build();
        response = client.newCall(request).execute();
        // 检查响应是否成功
        if (response.isSuccessful() && response.body() != null) {
            String responseBody = response.body().string();
            JSONObject jsonResponse = JSON.parseObject(responseBody);
            // 检查返回的 code 是否为 200
            if ("200".equals(jsonResponse.getString("code"))) {
                return jsonResponse.getString("data"); // 返回 location 中的 id
            } else {
                System.out.println("API 返回错误代码: " + jsonResponse.getString("code"));
            }
        } else {
            System.out.println("请求失败，状态码: " + response.code());
        }
        response.close();
        return null;
    }

    // 构建返回的html内容
    public static String buildContent(String json, PushData pushData) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(json);

        // 提取最低气温、最高气温
        ObjectReader objectReader = mapper.readerFor(new TypeReference<List<JsonNode>>() {
        });
        List<JsonNode> hourlyList = (objectReader).readValue(rootNode.get("hourly"));

        double minTemp = Double.MAX_VALUE;
        double maxTemp = Double.MIN_VALUE;
        for (JsonNode hour : hourlyList) {
            double temp = Double.parseDouble(hour.get("temp").asText());
            if (temp < minTemp) {
                minTemp = temp;
            }
            if (temp > maxTemp) {
                maxTemp = temp;
            }
        }
        // 提取今天天气
        String currWeather = hourlyList.get(0).get("text").asText();
        String currTemp = hourlyList.get(0).get("temp").asText();

        // 提取当前湿度
        String currHumidity = hourlyList.get(0).get("humidity").asText();

        // 提取当前风向、风力
        String currentWindDir = hourlyList.get(0).get("windDir").asText();
        String currentWindScale = hourlyList.get(0).get("windScale").asText();

        // 提取未来24小时最大降水概率
        int maxPop = 0;
        for (JsonNode hour : hourlyList) {
            int pop = Integer.parseInt(hour.get("pop").asText());
            if (pop > maxPop) {
                maxPop = pop;
            }
        }
        // 根据天气插入图片，具体有哪些api文档没写，根据运行情况再加
        String weatherImage = "";
        switch (currWeather) {
            case "晴":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-2-2509:30:06-%E6%99%B4%E5%A4%A9.png"; // 替换为晴天图片链接
                break;
            case "多云":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-2-2509:30:46-%E6%B5%93%E4%BA%91.png"; // 替换为多云图片链接
                break;
            case "小雨":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-2-2509:31:37-%E5%A4%A9%E6%B0%94-%E5%B0%8F%E9%9B%A8.png"; // 替换为小雨图片链接
                break;
            case "中雨":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-508:29:08-%E4%B8%AD%E9%9B%A8.png"; // 替换为中雨图片链接
                break;
            case "大雨":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-508:29:56-%E5%A4%A7%E9%9B%A8.png"; // 替换为大雨图片链接
                break;
            case "暴雨":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-508:31:00-%E5%A4%A7%E6%9A%B4%E9%9B%A8%E5%88%B0%E7%89%B9%E5%A4%A7%E6%9A%B4%E9%9B%A8.png"; // 替换为暴雨图片链接
                break;
            case "雷阵雨":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-508:31:46-%E9%9B%B7%E9%98%B5%E9%9B%A8.png"; // 替换为雷阵雨图片链接
                break;
            case "阴":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-2-2509:32:31-%E9%98%B4%E5%A4%A9.png"; // 替换为阴天图片链接
                break;
            case "雨夹雪":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-508:27:06-%E9%9B%A8%E5%A4%B9%E9%9B%AA.png";
                break;
                case "阵雪":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-1712:46:20-%E9%98%B5%E9%9B%AA2.png";
                break;
                case "小雪":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-1712:47:33-%E5%B0%8F%E9%9B%AA.png";
                break;
                case "中雪":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-1712:48:22-%E4%B8%AD%E9%9B%AA.png";
                break;
                case "大雪":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-1712:49:05-%E5%A4%A7%E9%9B%AA.png";
                break;
                case "暴雪":
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-3-1712:49:39-%E6%9A%B4%E9%9B%AA.png";
                break;
            default:
                weatherImage = "https://gitee.com/chen-superplus/personal-warehouse1/raw/master/img/2025-2-2509:33:21-%E7%8B%97%E5%A4%B4.png"; // 默认图片链接
        }

        // 构建HTML字符串
        StringBuilder htmlBuilder = new StringBuilder();
        htmlBuilder.append(
                "<body style='margin: 0; padding: 10px; min-height: 100vh; background: white; font-family: \"Segoe UI\", Tahoma, sans-serif;'>"
                        + "<div style='max-width: 600px; margin: 0 auto; background: rgba(255,255,255,0.98); border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);'>"

                        // 头部
                        + "<div style='padding: 15px; background: linear-gradient(135deg, #6da2ff 0%, #88ccff 100%);'>"
                        + "<div style='display: flex; align-items: center; color: white;'>"
                        + "<img src='" + weatherImage + "' style='width: 55px; height: 55px; flex-shrink: 0;'>"
                        + "<div style='flex: 1; text-align: center; padding-right: 20px;'>"
                        + "<h1 style='margin: 0; font-size: 22px;'>今日天气</h1>"
                        + "<div style='display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; justify-content: center;'>"
                        + "<span style='font-size: 28px; font-weight: bold;'>" + currTemp + "°C</span>"
                        + "<span style='font-size: 16px;'>" + currWeather + "</span>"
                        + "</div>"
                        + "</div>"
                        + "</div>"
                        + "</div>"

                        // 紧凑信息区
                        + "<div style='padding: 12px 15px; background: #f8f9fa; border-bottom: 1px solid #eee;'>"
                        + "<div style='display: flex; flex-wrap: nowrap; gap: 8px; overflow-x: auto;'>"
                        // 温度范围
                        + "<div style='flex: 1 0 22%; min-width: 22%; text-align: center; padding: 8px 5px; background: white; border-radius: 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); white-space: nowrap;'>"
                        + "<div style='color: #3a7bd5; font-size: 15px; font-weight: bold; overflow: hidden; text-overflow: ellipsis;'>" + String.format("%.0f", maxTemp) + "°C</div>"
                        + "<div style='font-size: 11px; color: #666; overflow: hidden; text-overflow: ellipsis;'>最高温度</div>"
                        + "</div>"
                        + "<div style='flex: 1 0 22%; min-width: 22%; text-align: center; padding: 8px 5px; background: white; border-radius: 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); white-space: nowrap;'>"
                        + "<div style='color: #00d2ff; font-size: 15px; font-weight: bold; overflow: hidden; text-overflow: ellipsis;'>" + String.format("%.0f", minTemp) + "°C</div>"
                        + "<div style='font-size: 11px; color: #666; overflow: hidden; text-overflow: ellipsis;'>最低温度</div>"
                        + "</div>"
                        // 风力信息
                        + "<div style='flex: 1 0 22%; min-width: 22%; text-align: center; padding: 8px 5px; background: white; border-radius: 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); white-space: nowrap;'>"
                        + "<div style='font-size: 14px; color: #495057; font-weight: bold; overflow: hidden; text-overflow: ellipsis;'>" + currentWindScale + "级</div>"
                        + "<div style='font-size: 11px; color: #666; overflow: hidden; text-overflow: ellipsis;'>" + currentWindDir + "</div>"
                        + "</div>"
                        // 湿度信息
                        + "<div style='flex: 1 0 22%; min-width: 22%; text-align: center; padding: 8px 5px; background: white; border-radius: 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); white-space: nowrap;'>"
                        + "<div style='color: #00d2ff; font-size: 15px; font-weight: bold; overflow: hidden; text-overflow: ellipsis;'>" + currHumidity + "%</div>"
                        + "<div style='font-size: 11px; color: #666; overflow: hidden; text-overflow: ellipsis;'>当前湿度</div>"
                        + "</div>"
                        + "</div>"
                        + "</div>"

                        // 倒计时预留位置
                        + "<div style='padding: 12px 15px 0; display: flex; flex-direction: column; gap: 10px;'>"
                        + "<div style='background: #fff3cd; padding: 10px; border-radius: 6px; text-align: center;'>"
                        + "<!-- 生日倒计时 -->"
                        + "<div style='color: #856404; font-size: 12px;'>"
                        + "🎂 生日倒计时：<br><span style='font-size: 15px; color: #d39e00;'>还剩"
                        + DateUtils.calculateBirthday(pushData.getBirthday()) + "天</span>"
                        + "</div>"
                        + "</div>"
                        + "<div style='background: #d4edda; padding: 10px; border-radius: 6px; text-align: center;'>"
                        + "<!-- 恋爱天数 -->"
                        + "<div style='color: #155724; font-size: 12px;'>"
                        + "❤️ 恋爱天数：<br><span style='font-size: 15px; color: #28a745;'>"
                        + DateUtils.calculateDaysDifference(pushData.getLoveDay()) + "天</span>"
                        + "</div>"
                        + "</div>"
                        + "</div>"

                        // 温馨提示
                        + "<div style='padding: 0 15px 15px; margin-top: 10px;'>"
                        + "<div style='background: #f8f9fa; padding: 10px; border-radius: 6px; margin-bottom: 10px;'>"
                        + "<div style='color: #3a7bd5; font-size: 12px; line-height: 1.4;'>宝宝, "
                        + getDressingAdvice(minTemp, maxTemp) + "</div>"
                        + "</div>"
                        + "<div style='background: #f8f9fa; padding: 10px; border-radius: 6px;'>"
                        + "<div style='color: #28a745; font-size: 12px; line-height: 1.4;'>" + getUmbrellaAdvice(maxPop)
                        + "</div>"
                        + "</div>"
                        + "</div>");
        // 每日一笑
        String jocker = getEveryJoker();
        if (jocker != null) {
            htmlBuilder.append("<div style='padding: 10px 15px 0; background: #f8f9fa; border-top: 1px solid #eee;'>"
                    + "<h3 style='margin: 0 0 6px 0; color: #0d6efd; font-size: 15px;'>每日一笑</h3>"
                    + "<div style='padding: 10px; background: white; border-radius: 6px;'>"
                    + "<p style='font-size: 13px; line-height: 1.5; margin: 0;'>" + jocker + "</p>"
                    + "</div>"
                    + "</div>");
        }

        htmlBuilder.append("</div></body>");
        return htmlBuilder.toString();
    }

    // 穿衣推荐 (基于26度穿衣法)
    private static String getDressingAdvice(double minTemp, double maxTemp) {
        // 使用26度穿衣法计算所需衣服温度
        // 公式：26°C - 当天温度 = 所需衣服温度
        double avgTemp = (minTemp + maxTemp) / 2; // 使用平均温度进行计算
        int clothingTemp = (int) Math.round(26 - avgTemp);
        
        // 根据所需衣服温度给出穿衣建议
        if (clothingTemp <= 0) {
            return "🔥 天气炎热（" + String.format("%.1f°C~%.1f°C", minTemp, maxTemp) + "），建议穿着短袖+防晒衣，记得及时补水降温！";
        } else if (clothingTemp <= 2) {
            return "👕 温度适中偏热（" + String.format("%.1f°C~%.1f°C", minTemp, maxTemp) + "），建议穿着短袖+薄外套，方便调节体温";
        } else if (clothingTemp <= 4) {
            return "👚 温度适中（" + String.format("%.1f°C~%.1f°C", minTemp, maxTemp) + "），建议穿着长袖衬衫+薄外套，舒适又实用";
        } else if (clothingTemp <= 6) {
            return "🧥 微凉天气（" + String.format("%.1f°C~%.1f°C", minTemp, maxTemp) + "），建议穿着针织衫+外套，温暖又时尚";
        } else if (clothingTemp <= 8) {
            return "🧣 凉爽天气（" + String.format("%.1f°C~%.1f°C", minTemp, maxTemp) + "），建议穿着厚毛衣+风衣，注意颈部保暖";
        } else if (clothingTemp <= 10) {
            return "🧥❄️ 寒冷天气（" + String.format("%.1f°C~%.1f°C", minTemp, maxTemp) + "），建议穿着厚外套+毛衣+围巾，全面保暖";
        } else {
            return "🧊 严寒天气（" + String.format("%.1f°C~%.1f°C", minTemp, maxTemp) + "），建议穿着羽绒服+加绒裤子+帽子手套，注意防寒保暖！";
        }
    }

    // 雨具推荐
    private static String getUmbrellaAdvice(int maxPop) {
        if (maxPop <= 30) {
            return "🌤️ 今日无雨（降水概率" + maxPop + "%），可以放心出门";
        } else if (maxPop > 30 && maxPop < 65) {
            return "🌦️ 可能降雨（降水概率" + maxPop + "%），建议随身携带折叠伞";
        } else {
            return "⛈️ 大概率降雨（降水概率" + maxPop + "%），请携带雨具并注意出行安全";
        }
    }
}